#include "rrrenderer.h"
#include <cstdio>
#include <SDL_image.h>
#include <SDL_endian.h>

RRRenderer rend;
RRRenderer rend2;

SDL_Surface *screen = NULL;
SDL_Surface *backscreen = NULL;
SDL_Surface *background_image = NULL;

void Update(void)
{
    /* here to code processes to update the state */
}

void DrawPixel(SDL_Surface *screen)
{
    Uint32 color;// = SDL_MapRGB(screen->format, R, G, B);

    if(SDL_MUSTLOCK(screen)) {
        if(SDL_LockSurface(screen) < 0) {
            return;
        }
    }

    int x, y;

    for(x=0; x<640; x++)
        for(y=0; y<480; y++) {
            Uint32 *bufp;
            bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
            *bufp = 0;
        }

    rend.rrBegin(RR_TRIANGLE);
    rend.rrColor4f(1.0f, 1.0f, 0.0f, 0.0f);
    rend.rrSetVert3f(1.2f, 0.0f, -0.8f);
    rend.rrColor4f(1.0f, 0.0f, 0.0f, 1.0f);
    rend.rrSetVert3f(-1.2f, 0.0f, -0.8f);
    rend.rrColor4f(1.0f, 0.0f, 1.0f, 0.0f);
    rend.rrSetVert3f(0.0f, -1.4f, 0.0f);
    rend.rrEnd();

    rend2.rrBegin(RR_TRIANGLE);
    rend2.rrColor4f(1.0f, 1.0f, 0.0f, 0.0f);
    rend2.rrSetVert3f(1.2f, 0.0f, -0.8f);
    rend2.rrColor4f(1.0f, 0.0f, 0.0f, 1.0f);
    rend2.rrSetVert3f(-1.2f, 0.0f, -0.8f);
    rend2.rrColor4f(1.0f, 0.0f, 1.0f, 0.0f);
    rend2.rrSetVert3f(0.0f, 1.2f, 0.0f);
    rend2.rrEnd();

    //puts("Now Rendering is over");
    int pnum;

    pnum = rend.rrGetPointsNum();
    for(int i=0; i<pnum; i++) {
        RRFragment point;
        point = rend.rrGetPoint(i);
        color = SDL_MapRGB(screen->format, (int)(point.c[1] * 255), (int)(point.c[2] * 255), (int)(point.c[3] * 255));
        Uint32 *bufp;
        bufp = (Uint32 *)screen->pixels + point.y * screen->pitch/4 + point.x;
        *bufp = color;
    }

    pnum = rend2.rrGetPointsNum();
    for(int i=0; i<pnum; i++) {
        RRFragment point;
        point = rend2.rrGetPoint(i);
        color = SDL_MapRGB(screen->format, (int)(point.c[1] * 255), (int)(point.c[2] * 255), (int)(point.c[3] * 255));
        Uint32 *bufp;
        bufp = (Uint32 *)screen->pixels + point.y * screen->pitch/4 + point.x;
        *bufp = color;
    }

    //puts("Processing screen is over");

    if(SDL_MUSTLOCK(screen)) {
        SDL_UnlockSurface(screen);
    }
    // SDL_UpdateRect(screen, x, y, 1, 1);
}

void Draw(void)
{
    /* SDL_BlitSurface(background_image, NULL, screen, NULL); */

    /* here to code drawing processes  */
    DrawPixel(backscreen);

    // update screen
    SDL_BlitSurface(backscreen, NULL, screen, NULL);
    SDL_Flip(screen);

    //puts("Im in Draw");
    // SDL_UpdateRect(backscreen, 0, 0, 0, 0);
}

int Initialize(void)
{
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) {
        fprintf(stderr, "failed to initialize SDL: %s\n", SDL_GetError());
        return -1;
    }

    SDL_WM_SetCaption("My SDL Sample", NULL);

    screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);

    backscreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

    if(screen == NULL) {
        fprintf(stderr, "failed to initialize the screen: %s\n", SDL_GetError());
        SDL_Quit();
        return -1;
    }

    return 0;
}

void MainLoop(void)
{
    SDL_Event event;
    double next_frame = SDL_GetTicks();
    double wait = 1000.0 / 60;

    while(1) {
        //puts("Im in MainLoop");
        /* deal with all events */
        while(SDL_PollEvent(&event)) {
            if((event.type == SDL_QUIT) || (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE)) {
                //puts("Im dealing with SDL_QUIT");
                return;
            }
        }
        if(SDL_GetTicks() >= next_frame) {
            //puts("Im dealing with Update");
            Update();
            if(SDL_GetTicks() < next_frame + wait) {
                //puts("im dealing with Draw");
                Draw();
            }
            next_frame += wait;
            SDL_Delay(0);
        }
    }
}

void Finalize(void)
{
    /* here to free images and sounds */
    // SDL_FreeSurface(background_image);

    SDL_Quit();
}

int main(int argc, char *argv[])
{
    if(Initialize() < 0)
        return -1;

    // printf("%d\n", screen->pitch);

    MainLoop();

    Finalize();

    return 0;
}

